<template>
  <div class="setup-role-container">
    <table-bar @search="handleSearch" @reset="handleReset" />

    <!-- 搜索表单 -->
    <div class="search-form">
      <el-form inline :model="searchData">
        <el-form-item label="角色名">
          <el-input
            v-model="searchData.search"
            placeholder="请输入角色名"
            style="width: 200px"
            maxlength="20"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="handleReset">重置</el-button>
          <el-button type="success" @click="handleAddRole">新增角色</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 角色表格 -->
    <art-table
      :data="tableData"
      :loading="loading"
      :pagination="true"
      :total="total"
      :current-page="searchData.page"
      :page-size="searchData.pageSize"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      highlight-current-row
      show-header-background
    >
      <el-table-column prop="roleId" label="角色ID" min-width="120" />
      <el-table-column prop="roleName" label="角色名称" min-width="150" />
      <el-table-column prop="roleDescribe" label="描述" min-width="200" />
      <el-table-column label="操作" width="180" fixed="right">
        <template #default="scope">
          <div class="table-actions">
            <button-table type="edit" @click="handleEditRole(scope.row)" />
            <el-popconfirm title="确认删除此角色吗？" @confirm="handleDeleteRole(scope.row.roleId)">
              <template #reference>
                <button-table type="delete" @click.stop="() => {}" />
              </template>
            </el-popconfirm>
            <el-button link type="primary" @click="handleAssignPermission(scope.row)"
              >分配权限</el-button
            >
          </div>
        </template>
      </el-table-column>
    </art-table>

    <!-- 新增/编辑角色对话框 -->
    <el-dialog
      v-model="roleDialogVisible"
      :title="isEdit ? '编辑角色' : '新增角色'"
      width="30%"
      center
      :close-on-click-modal="false"
      @closed="onRoleDialogClosed"
    >
      <el-form ref="roleFormRef" :model="roleForm" label-width="100px" :rules="roleFormRules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" maxlength="20" />
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDescribe">
          <el-input
            v-model="roleForm.roleDescribe"
            placeholder="请输入角色描述"
            maxlength="60"
            type="textarea"
            :rows="3"
          />
        </el-form-item>
        <el-form-item label="平台登录账号" prop="username">
          <el-input v-model="roleForm.username" placeholder="请输入平台登录账号" maxlength="20" />
        </el-form-item>
        <el-form-item label="昵称" prop="name">
          <el-input v-model="roleForm.name" placeholder="请输入昵称" maxlength="20" />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-select v-model="roleForm.sex" placeholder="请选择性别">
            <el-option label="男" value="男" />
            <el-option label="女" value="女" />
          </el-select>
        </el-form-item>
        <el-form-item label="账户手机号" prop="phone">
          <el-input v-model="roleForm.phone" placeholder="请输入账户手机号" maxlength="11" />
        </el-form-item>
        <el-form-item label="账户登录密码" prop="password">
          <el-input v-model="roleForm.password" type="password" placeholder="请输入账户登录密码" maxlength="20" />
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="roleForm.email" placeholder="请输入邮箱" maxlength="50" />
        </el-form-item>
        <el-form-item label="是否启用" prop="state">
          <el-switch
            v-model="roleForm.state"
            :active-value="1"
            :inactive-value="0"
            active-text="启用"
            inactive-text="禁用"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="roleDialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="handleRoleSubmit"
            >确定</el-button
          >
        </div>
      </template>
    </el-dialog>

    <!-- 分配权限对话框 -->
    <el-dialog
      v-model="permissionDialogVisible"
      title="分配权限"
      width="50%"
      center
      :close-on-click-modal="false"
      @closed="onPermissionDialogClosed"
      class="permission-dialog"
    >
      <el-form :model="permissionForm" label-width="80px">
        <el-form-item label="角色名称">
          <span style="line-height: 32px; color: #666">{{ currentRoleName }}</span>
        </el-form-item>
        <el-form-item label="权限列表">
          <div class="permission-tree-container">
            <el-tree
              ref="permissionTreeRef"
              :data="permissionsList"
              show-checkbox
              render-after-expand
              default-expand-all
              node-key="permissionId"
              :props="permissionTreeProps"
              @check-change="handleCheckChange"
            />
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="permissionDialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="permissionLoading" @click="handlePermissionSubmit"
            >确认</el-button
          >
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive } from 'vue'
  import { ElMessage } from 'element-plus'
  import type { FormInstance, ElTree } from 'element-plus'

  // API 导入
  import { SetupService } from '@/api/setupApi'
  import { ApiStatus } from '@/utils/http/status'

  // 搜索数据
  const searchData = reactive({
    search: '',
    page: 1,
    pageSize: 10
  })

  // 表格数据
  const tableData = ref<any[]>([])
  const total = ref(0)
  const loading = ref(false)

  // 角色表单数据
  const roleFormRef = ref<FormInstance | null>(null)
  const roleDialogVisible = ref(false)
  const isEdit = ref(false)
  const submitLoading = ref(false)

  // 角色表单
  const roleForm = reactive({
    roleId: 0,
    roleName: '',
    roleDescribe: '',
    username: '',
    name: '',
    sex: '',
    phone: '',
    password: '',
    email: '',
    avatar: '',
    state: 1 // 默认启用
  })

  // 角色表单验证规则
  const roleFormRules = {
    roleName: [
      { required: true, message: '请输入角色名称', trigger: 'blur' },
      { min: 2, max: 20, message: '角色名称长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    roleDescribe: [{ max: 60, message: '角色描述不能超过 60 个字符', trigger: 'blur' }],
    username: [
      { required: true, message: '请输入平台登录账号', trigger: 'blur' },
      { min: 5, max: 20, message: '账号长度在 5 到 20 个字符', trigger: 'blur' }
    ],
    name: [
      { required: true, message: '请输入昵称', trigger: 'blur' },
      { min: 2, max: 20, message: '昵称长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    phone: [
      { required: true, message: '请输入账户手机号', trigger: 'blur' },
      { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
    ],
    password: [
      { required: true, message: '请输入账户登录密码', trigger: 'blur' },
      { min: 8, max: 11, message: '密码长度在 8 到 11 个字符', trigger: 'blur' }
    ],
    email: [
      { pattern: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/, message: '请输入正确的邮箱地址', trigger: 'blur' }
    ],
    state: [{ required: true, message: '请选择是否启用', trigger: 'change' }]
  }

  // 权限分配相关
  const permissionDialogVisible = ref(false)
  const permissionTreeRef = ref<InstanceType<typeof ElTree> | null>(null)
  const permissionLoading = ref(false)
  const permissionsList = ref<any[]>([])

  // 类型断言函数，确保TypeScript正确识别ref类型
  const getPermissionTree = (): InstanceType<typeof ElTree> | null => {
    return permissionTreeRef.value
  }
  const currentRoleName = ref('')
  const currentRoleId = ref('')

  // 权限树配置
  const permissionTreeProps = {
    label: 'permissionName',
    children: 'children'
  }

  // 权限表单
  const permissionForm = reactive({
    permissionIds: [] as number[]
  })

  // 初始化数据
  onMounted(() => {
    getRolesList()
  })

  // 获取角色列表
  const getRolesList = async () => {
    loading.value = true
    try {
      const res = await SetupService.roleGetAll({
        search: searchData.search,
        page: searchData.page,
        pageSize: searchData.pageSize
      })
      if (res.code === ApiStatus.success) {
        // 修复类型问题：根据实际返回的数据结构调整
        if (Array.isArray(res.data)) {
          // 如果res.data直接是数组
          tableData.value = res.data
          total.value = res.data.length
        } else if (res.data && typeof res.data === 'object' && 'list' in res.data) {
          // 如果res.data包含list字段（分页结构）
          const pageData = res.data as { list: any[]; total?: number }
          tableData.value = pageData.list || []
          total.value = pageData.total || 0
        } else {
          // 其他情况，初始化为空数组
          tableData.value = []
          total.value = 0
        }
      } else {
        ElMessage.error(res.message || '获取角色列表失败')
        tableData.value = []
        total.value = 0
      }
    } catch (error) {
      ElMessage.error('获取角色列表失败')
      console.error(error)
      tableData.value = []
      total.value = 0
    } finally {
      loading.value = false
    }
  }

  // 处理搜索
  const handleSearch = () => {
    searchData.page = 1
    getRolesList()
  }

  // 处理重置
  const handleReset = () => {
    searchData.search = ''
    searchData.page = 1
    searchData.pageSize = 10
    getRolesList()
  }

  // 处理分页大小变化
  const handleSizeChange = (size: number) => {
    searchData.pageSize = size
    getRolesList()
  }

  // 处理当前页变化
  const handleCurrentChange = (current: number) => {
    searchData.page = current
    getRolesList()
  }

  // 新增角色
  const handleAddRole = () => {
    isEdit.value = false
    // 重置表单
    Object.assign(roleForm, {
      roleId: 0,
      roleName: '',
      roleDescribe: '',
      username: '',
      name: '',
      sex: '',
      phone: '',
      password: '',
      email: '',
      avatar: '',
      state: 1 // 默认启用
    })
    // 清空表单验证
    if (roleFormRef.value) {
      roleFormRef.value.clearValidate()
    }
    roleDialogVisible.value = true
  }

  // 编辑角色
  const handleEditRole = async (row: any) => {
    isEdit.value = true
    // 清空表单验证
    if (roleFormRef.value) {
      roleFormRef.value.clearValidate()
    }

    try {
      // 获取角色详情
      const res = await SetupService.roleGetById({ id: row.roleId })
      if (res.code === ApiStatus.success) {
        const roleInfo = res.data || {}
        // 填充表单数据
        Object.assign(roleForm, {
          roleId: roleInfo.roleId,
          roleName: roleInfo.roleName,
          roleDescribe: roleInfo.roleDescribe,
          username: roleInfo.username || '',
          name: roleInfo.name || '',
          sex: roleInfo.sex || '',
          phone: roleInfo.phone || '',
          password: '', // 不填充密码
          email: roleInfo.email || '',
          avatar: roleInfo.avatar || '',
          state: roleInfo.state || 1
        })
        roleDialogVisible.value = true
      } else {
        ElMessage.error(res.message || '获取角色详情失败')
      }
    } catch (error) {
      ElMessage.error('获取角色详情失败')
      console.error(error)
    }
  }

  // 删除角色
  const handleDeleteRole = async (roleId: string | number) => {
    try {
      // 使用roleId作为唯一标识
      const res = await SetupService.roleDelete({ roleId: Number(roleId) })
      if (res.code === ApiStatus.success) {
        ElMessage.success('删除成功')
        getRolesList()
      } else {
        ElMessage.error(res.message || '删除失败')
      }
    } catch (error) {
      ElMessage.error('删除失败')
      console.error(error)
    }
  }

  // 提交角色表单
  const handleRoleSubmit = async () => {
    if (!roleFormRef.value) return

    try {
      await roleFormRef.value.validate()
      submitLoading.value = true

      const formData = {
        ...roleForm
      }

      let res
      // 直接使用formData作为提交数据，不添加id字段
      const submitData = formData

      // 获取当前时间的毫秒级时间戳
      const currentTimestamp = new Date().getTime()

      if (isEdit.value) {
        // 编辑角色
        // 编辑时只更新updateTimeStamp
        submitData.updateTimeStamp = currentTimestamp
        res = await SetupService.roleUpdate(submitData)
      } else {
        // 新增角色
        // 新增时同时设置createTimeStamp和updateTimeStamp
        submitData.createTimeStamp = currentTimestamp
        submitData.updateTimeStamp = currentTimestamp
        res = await SetupService.roleAdd(submitData)
      }

      if (res.code === ApiStatus.success) {
        ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
        roleDialogVisible.value = false
        getRolesList()
      } else {
        ElMessage.error(res.message || (isEdit.value ? '编辑失败' : '新增失败'))
      }
    } catch (error) {
      // 表单验证失败不处理，其他错误处理
      if (error instanceof Error) {
        ElMessage.error(isEdit.value ? '编辑失败' : '新增失败')
        console.error(error)
      }
    } finally {
      submitLoading.value = false
    }
  }

  // 分配权限
  const handleAssignPermission = async (row: any) => {
    currentRoleId.value = row.roleId
    currentRoleName.value = row.roleName
    permissionDialogVisible.value = true

    try {
      // 获取角色已有权限
      const res = await SetupService.getRolePermission({ roleId: row.roleId })
      console.log('API完整响应:', res)
      if (res.code === ApiStatus.success) {
        console.log('成功获取角色权限', res.data)
        // 检查数据结构
        console.log('权限菜单数据结构:', res.data?.menus || res.data?.permissions)
        console.log('权限IDs数据结构:', res.data?.permissionIds || res.data?.ids)

        // 验证数据类型并处理不同情况
        let menusData = []
        let permissionIdsData = []

        // 检查res.data本身是否就是期望的数据结构
        if (res.data && Array.isArray(res.data.menus) && Array.isArray(res.data.permissionIds)) {
          menusData = res.data.menus
          permissionIdsData = res.data.permissionIds
        }
        // 检查res.data是否包含data字段
        else if (
          res.data?.data &&
          Array.isArray(res.data.data.menus) &&
          Array.isArray(res.data.data.permissionIds)
        ) {
          menusData = res.data.data.menus
          permissionIdsData = res.data.data.permissionIds
        }
        // 检查res.data是否包含permissions和ids字段
        else if (res.data && Array.isArray(res.data.permissions) && Array.isArray(res.data.ids)) {
          menusData = res.data.permissions
          permissionIdsData = res.data.ids
        }
        // 检查res.data是否直接是菜单数组
        else if (Array.isArray(res.data)) {
          menusData = res.data
          permissionIdsData = []
        }
        // 其他情况，初始化为空数组
        else {
          console.warn('未识别的数据结构:', res.data)
          menusData = []
          permissionIdsData = []
        }

        // 将权限数据中的childs字段转换为children字段，以便el-tree能正确展示子级菜单
        const convertedMenusData = convertChildsToChildren(menusData)

        console.log('处理后的菜单数据:', convertedMenusData)
        console.log('处理后的权限IDs数据:', permissionIdsData)

        // 设置权限列表
        permissionsList.value = convertedMenusData

        // 延迟设置选中状态，确保树已经渲染
        setTimeout(() => {
          const tree = getPermissionTree()
          console.log('tree:', tree)
          
          // 先清空之前的选中状态和表单数据
          if (tree) {
            tree.setCheckedKeys([])
          }
          
          // 先将权限表单设置为空数组
          permissionForm.permissionIds = []
          
          if (tree) {
            if (permissionIdsData.length > 0) {
              // 将数字数组转换为字符串数组，因为element-plus tree组件的node-key是字符串
              const stringIds = permissionIdsData.map((id) => id.toString())
              console.log('原始权限IDs数据:', permissionIdsData)
              console.log('转换为字符串的权限IDs:', stringIds)
              
              // 重要：使用setChecked方法逐个设置节点状态，而不是使用setCheckedKeys
              // 这是因为setCheckedKeys不能正确处理半选中状态
              // 首先需要找到所有的节点并清除它们的选中状态
              function resetAllNodes(nodes: any[], nodeList: any[] = []) {
                nodes.forEach(node => {
                  const nodeKey = node.permissionId?.toString()
                  if (nodeKey) {
                    tree.setChecked(nodeKey, false, false)
                    nodeList.push(nodeKey)
                  }
                  if (node.children && node.children.length) {
                    resetAllNodes(node.children, nodeList)
                  }
                })
                return nodeList
              }
              
              // 重置所有节点的选中状态
              const allNodeKeys = resetAllNodes(convertedMenusData)
              console.log('所有节点的key列表:', allNodeKeys)
              
              // 然后逐个设置有权限的节点
              stringIds.forEach(key => {
                if (allNodeKeys.includes(key)) {
                  // 使用setChecked方法设置选中状态，第三个参数为false表示不级联
                  tree.setChecked(key, true, false)
                }
              })
              
              // 在设置完树的选中状态后，手动触发一次check-change事件
              setTimeout(() => {
                // 手动调用handleCheckChange来更新permissionForm.permissionIds
                handleCheckChange()
              }, 50)
            } else {
              console.log('权限IDs数据为空，不设置选中状态')
            }
          } else {
            console.log('tree组件未获取到')
          }
        }, 100)
      } else {
        ElMessage.error(res.message || '获取角色权限失败')
      }
    } catch (error) {
      ElMessage.error('获取角色权限失败')
      console.error(error)
    }
  }

  // 将数据中的 childs 属性转换为 children 属性
  const convertChildsToChildren = (data: any[]): any[] => {
    return data.map((item) => {
      const newItem = { ...item }
      // 如果存在 childs 属性，将其转换为 children 属性
      if (newItem.childs) {
        newItem.children = convertChildsToChildren(newItem.childs)
        delete newItem.childs
      }
      return newItem
    })
  }

  // 处理权限选择变化
  const handleCheckChange = () => {
    const tree = getPermissionTree()
    if (tree) {
      // 获取完全选中的节点
      const checkedKeys = tree.getCheckedKeys(false)
      // 获取半选中的节点
      const halfCheckedKeys = tree.getHalfCheckedKeys()
      // 合并完全选中和半选中的节点
      const allSelectedKeys = [...new Set([...checkedKeys, ...halfCheckedKeys])]
      
      console.log('完全选中的权限keys:', checkedKeys)
      console.log('半选中的权限keys:', halfCheckedKeys)
      console.log('所有选中的权限keys:', allSelectedKeys)
      
      permissionForm.permissionIds = allSelectedKeys
        .map((key) => {
          // 确保key是数字类型
          if (typeof key === 'string') {
            const num = parseInt(key, 10)
            return isNaN(num) ? 0 : num
          }
          return Number(key)
        })
        .filter((id) => id > 0)

      console.log('更新后的permissionIds:', permissionForm.permissionIds)
    }
  }

  // 提交权限分配
  const handlePermissionSubmit = async () => {
    try {
      permissionLoading.value = true
      const res = await SetupService.distribution({
        roleId: Number(currentRoleId.value),
        permissionIds: permissionForm.permissionIds
      })

      if (res.code === ApiStatus.success) {
        ElMessage.success('权限分配成功')
        permissionDialogVisible.value = false
      } else {
        ElMessage.error(res.message || '权限分配失败')
      }
    } catch (error) {
      ElMessage.error('权限分配失败')
      console.error(error)
    } finally {
      permissionLoading.value = false
    }
  }

  // 角色对话框关闭时
  const onRoleDialogClosed = () => {
    if (roleFormRef.value) {
      roleFormRef.value.clearValidate()
    }
  }

  // 权限对话框关闭时
  const onPermissionDialogClosed = () => {
    permissionsList.value = []
    permissionForm.permissionIds = []
    currentRoleName.value = ''
    currentRoleId.value = ''
  }
</script>

<style lang="scss" scoped>
  .setup-role-container {
    padding: 20px;

    .search-form {
      padding: 15px;
      margin-bottom: 20px;
      background-color: var(--art-gray-50);
      border-radius: 4px;
    }

    .table-actions {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;

      :deep(.btn-text) {
        margin-right: 0 !important;
      }
    }

    .dialog-footer {
      display: flex;
      gap: 10px;
      justify-content: flex-end;
    }

    .permission-tree-container {
      max-height: 400px; 
      padding: 10px; 
      overflow-y: auto; 
      border: 1px solid var(--art-border-color-light); 
      border-radius: 4px;
    }

    // 权限树勾选框居中显示
    :deep(.el-tree-node__content) {
      display: flex;
      align-items: center;
    }

    :deep(.el-checkbox) {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    :deep(.el-checkbox__input) {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    // 更精确的勾选标记居中样式
    :deep(.el-checkbox__inner) {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    :deep(.el-checkbox__input.is-checked .el-checkbox__inner::after) {
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%) rotate(45deg);
      position: absolute;
    }

    // 权限对话框居中样式
    :deep(.permission-dialog .el-dialog__body) {
      display: flex;
      justify-content: center;
    }

    :deep(.permission-dialog .el-form) {
      width: 100%;
    }

    :deep(.permission-dialog .el-form-item__content) {
      justify-content: center;
    }

    :deep(.permission-dialog .permission-tree-container) {
      display: flex;
      justify-content: center;
      width: 100%;
    }
  }

  // 响应式适配
  $device-notebook: 1600px;
  $device-ipad-pro: 1180px;
  $device-ipad: 800px;
  $device-ipad-vertical: 900px;
  $device-phone: 500px;

  // 平板横屏及更小屏幕
  @media screen and (max-width: #{$device-ipad-pro}) {
    .setup-role-container {
      padding: 10px;

      .search-form {
        padding: 10px;
      }

      .search-form .el-form {
        display: flex;
        flex-direction: column;
        gap: 10px;
        align-items: flex-start;
      }

      .search-form .el-form-item {
        margin-bottom: 10px;
      }

      .search-form .el-form-item:nth-last-child(1) {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
      }

      .permission-tree-container {
        max-height: 300px;
      }
    }
  }

  // 平板竖屏及更小屏幕
  @media screen and (max-width: #{$device-ipad-vertical}) {
    .setup-role-container {
      padding: 8px;
    }

    // 调整对话框宽度
    :deep(.el-dialog) {
      width: 90% !important;
      max-width: 500px;
    }
  }

  // 手机屏幕
  @media screen and (max-width: #{$device-phone}) {
    .setup-role-container {
      padding: 5px;

      .search-form .el-input {
        width: 100% !important;
      }

      .table-actions {
        flex-direction: column;
        gap: 5px;
      }

      // 调整表格样式，确保内容能正常显示
      :deep(.el-table) {
        font-size: 12px;
      }

      :deep(.el-table__header th),
      :deep(.el-table__body td) {
        padding: 8px 4px;
      }
    }
  }
</style>
